using System.Linq;
using System.Collections.Generic;
using System.Web.Mvc;
using CookComputing.XmlRpc;
using System.Web;
using System.IO;
using System.Web.Security;
using MyAlbum.Services;
using MyAlbum.Utility;
using System;
using System.Text;
using System.Web.Routing;
using MyAlbum.Model;
namespace PersonalAlbum.Controllers
{
    public class MetaWebLogAPIController : Controller
    {
        private IBlogService _blogService;
        public MetaWebLogAPIController()
        {
            this._blogService = ObjectFactory.GetInstance<IBlogService>();
        }
        //
        // GET: /MetaWebLogAPI/

        public ActionResult Index()
        {
            StringWriter writer = new StringWriter();
            var response = new HttpResponse(writer);
            XmlRpcHttpRequest httpReq = new XmlRpcHttpRequest(System.Web.HttpContext.Current.Request);
            XmlRpcHttpResponse httpResp = new XmlRpcHttpResponse(System.Web.HttpContext.Current.Response);
            UrlHelper url = new UrlHelper(this.ControllerContext.RequestContext);
            new MetaWeblogAPI(httpReq, httpResp, _blogService, url);
            return new TextResult("");
        }

    }

    public class MetaWeblogAPI : XmlRpcService, IMetaWeblog
    {

        #region Public Constructors


        private IBlogService _blogService;
        private UrlHelper _url;
        public MetaWeblogAPI(XmlRpcHttpRequest httpReq,
            XmlRpcHttpResponse httpResp,
            IBlogService blogService,
            UrlHelper url)
        {
            this._url = url;
            this._blogService = blogService;
            base.HandleHttpRequest(httpReq, httpResp);
        }



        #endregion



        #region IMetaWeblog Members



        string IMetaWeblog.AddPost(string blogid, string username, string password,

            Post post, bool publish)
        {

            if (ValidateUser(username, password))
            {                
                if (string.IsNullOrEmpty(post.title))
                {
                    post.title = "title";
                }
                var p = ConvertBlog(post);
                var result = new MyAlbum.Utility.GenericValidationSummary();
                string id = this._blogService.AddPost(p, null, result);


                if (result.IsValid)
                {
                    return id;
                }
                else
                {
                    throw new XmlRpcFaultException(0, FormatErrors(result.Errors));
                }

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }

        private PostEntry ConvertBlog(Post post)
        {
            var p = new PostEntry();
            p.UserName= post.userid;
            List<Tag> tags=new List<Tag>();
            foreach (var name in post.categories)
            {
                tags.Add(new Tag()
                {
                     Name = name
                });
            }
            p.Tags=tags;
            p.DateCreated = post.dateCreated;
            p.Title = post.title;
            p.Content = post.description;
            return p;
        }

        private string FormatErrors(Dictionary<string, string> dictionary)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in dictionary.Keys)
            {
                sb.Append(item);
                sb.Append(":");
                sb.AppendLine(dictionary[item]);
            }
            return sb.ToString();
        }



        bool IMetaWeblog.UpdatePost(string postid, string username, string password,
            Post post, bool publish)
        {
            if (ValidateUser(username, password))
            {
                try
                {
                    var p = ConvertBlog(post);
                    p.ID = postid;
                    var validationSummary = new GenericValidationSummary();
                    this._blogService.UpdatePost(p, validationSummary);
                    bool result = validationSummary.IsValid;
                    return result;
                }
                catch (Exception e1)
                {
                    throw new XmlRpcFaultException(0, "Error updating");
                }
            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        Post IMetaWeblog.GetPost(string postid, string username, string password)
        {

            if (ValidateUser(username, password))
            {


                var item = this._blogService.GetPost(postid);
                if (item != null)
                {
                    return ConvertBlog(item);

                }
                else
                {
                    throw new XmlRpcFaultException(0, "Post not found");
                }

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }

        private Post ConvertBlog(PostEntry item)
        {
            Post post = new Post();
            post.description = item.Content;
            List<string> categories = new List<string>();
            foreach (var cat in item.Tags)
            {
                categories.Add(cat.Name);
            }
            post.categories = categories.ToArray();
            post.dateCreated = item.DateCreated;
            post.postid = item.ID;
            post.title = item.Title;
            post.userid = item.UserName;
            post.permalink = this._url.Action("Details", "Blog", new { id = item.ID });
            return post;
        }



        CategoryInfo[] IMetaWeblog.GetCategories(string blogid, string username, string password)
        {

            if (ValidateUser(username, password))
            {

                List<CategoryInfo> categoryInfos = new List<CategoryInfo>();
                var items = _blogService.GetCategories();


                foreach (var item in items)
                {
                    categoryInfos.Add(new CategoryInfo()
                    {
                        title = item.Name,
                        description = item.Name,
                        categoryid = item.Id.ToString(),
                        htmlUrl = _url.Action("Tag", "Blog", new { id = item.Name }),
                        rssUrl = string.Empty

                    });
                }
                return categoryInfos.ToArray();

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        Post[] IMetaWeblog.GetRecentPosts(string blogid, string username, string password,

            int numberOfPosts)
        {

            if (ValidateUser(username, password))
            {

                List<Post> posts = new List<Post>();
                foreach (var item in this._blogService.GetPosts(1, 10, null))
                {
                    posts.Add(ConvertBlog(item));
                }
                return posts.ToArray();

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        MediaObjectInfo IMetaWeblog.NewMediaObject(string blogid, string username, string password,

            MediaObject mediaObject)
        {

            if (ValidateUser(username, password))
            {
                if (string.IsNullOrEmpty(mediaObject.name))
                {
                    throw new XmlRpcFaultException(0, "File name can not be empty");
                }

                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/Content/BlogsData"), mediaObject.name);
                if (File.Exists(path))
                {
                    throw new XmlRpcFaultException(0, "File name already exists");
                }
                if (!Directory.Exists(Path.GetDirectoryName(path)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
                }
                MediaObjectInfo objectInfo = new MediaObjectInfo();
                System.IO.File.WriteAllBytes(path, mediaObject.bits);
                objectInfo.url = _url.Content("~/Content/BlogsData/" + mediaObject.name.TrimStart('/'));
                return objectInfo;

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        bool IMetaWeblog.DeletePost(string key, string postid, string username, string password, bool publish)
        {

            if (ValidateUser(username, password))
            {
                bool result = false;
                this._blogService.DeletePost(postid);
                return result;
            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        BlogInfo[] IMetaWeblog.GetUsersBlogs(string key, string username, string password)
        {

            if (ValidateUser(username, password))
            {

                List<BlogInfo> infoList = new List<BlogInfo>();
                infoList.Add(new BlogInfo()
                {
                    blogid = "1234",
                    blogName = "PersonalAlbum",
                    url = _url.Action("Index", "Blog")
                });
                // TODO: Implement your own logic to get blog info objects and set the infoList

                return infoList.ToArray();

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        UserInfo IMetaWeblog.GetUserInfo(string key, string username, string password)
        {

            if (ValidateUser(username, password))
            {

                UserInfo info = new UserInfo();



                // TODO: Implement your own logic to get user info objects and set the info



                return info;

            }

            throw new XmlRpcFaultException(0, "User is not valid!");

        }



        #endregion



        #region Private Methods



        private bool ValidateUser(string username, string password)
        {
            return Membership.ValidateUser(username, password);
        }



        #endregion

    }
}
